#!/usr/bin/perl
# -Wall
#use strict;
#
# VSS-to-CVS migration script
# Based on an original by Brett Wooldridge (brettw@riseup.com)
# http://www.riseup.com/~brettw/dev/VSS2Subversion.html
# The restart and dump users options have not been implemented

$DEBUG = 1;

$SSREPO = "";
$SSPROJ = "";
$SSHOME = "";
$SSCMD = "";
$REPOS = "";
$RESTART = 0;
$DUMPUSERS = 0;

if ($DEBUG == 1)
{
	open(STDERR, "> migrate.log");
}

$PHASE = 0;
&parse_args(@ARGV);
&setup();
if ($RESTART > 0 )
{
	&restart();
}

if ($PHASE < 1)
{
	&build_hierarchy();
}
if ($PHASE < 2)
{
	&build_filelist();
}
if ($PHASE < 3)
{
	&build_histories();
}
if ($DUMPUSERS > 0 )
{
	&dump_users();
}
if ($PHASE < 4)
{
	&create_directories;
	&import_directories;
}
if ($PHASE < 5)
{
	&checkout_directories;
}

# &interleave_histories;
&extract_and_import;

if ($DEBUG)
{
	close(DEBUG);
}

print STDOUT "Finished\n";
exit;


##############################################################
# Parse Command-line arguments
#
sub parse_args
{
	$argc = @ARGV;
	if ($argc < 1)
	{
		print "migrate: missing command arguments\n";
		print "Try 'migrate --help' for more information\n\n";
		exit -1;
	}

	if ($ARGV[0] eq '--help')
	{
		print "Usage: migrate [options] project\n\n";
		print "Migrate a Visual SourceSafe project to CVS.\n\n";
		print "  --ssrepo=<dir>\trepository path, e.g. \\\\share\\vss\n";
		print "  --sshome=<dir>\tVSS installation directory\n";
		print "  --repos=<url>\t\tURL for the Subversion repository\n";
		print "  --dumpusers\t\tafter pre-processing the VSS repository, create a\n";
		print "\t\t\tusers.txt file.\n";
		exit -1;
	}

	for ($i = 0; $i < $argc; $i++)
	{
		$arg = $ARGV[$i];
		if ($arg eq '--restart')
		{
			$RESTART = 1;
		}
		elsif ($arg eq '--dumpusers')
		{
			$DUMPUSERS = 1;
		}
		elsif ($arg =~ /\-\-ssrepo\=/)
		{
			$SSREPO = $';
		}
		elsif ($arg =~ /\-\-sshome\=/)
		{
			$SSHOME = $';
		}
		elsif ($arg =~ /\-\-repos\=/)
		{
			$REPOS = $';
		}
		elsif ($arg =~ /\-\-force\-user\=/)
		{
			$FORCEUSER = $';
		}
		else
		{
			$SSPROJ = $arg;
		}
	}
	
	if ($SSPROJ !~ /^\$\/\w+/)
	{
		print "Error: missing project specification, must be of the form \$/project\n\n";
		exit -1;
	}
}


##############################################################
# Check environment and setup globals
#
sub setup
{
	$SSREPO = $ENV{'SSDIR'} unless length($SSREPO) > 0;
	if ($SSREPO eq '' || length($SSREPO) == 0)
	{
		die "Environment variable SSDIR must point to a SourceSafe repository.";
	}
	$SSHOME = $ENV{'SS_HOME'} unless length($SSHOME) > 0;

	if ($SSHOME eq '' || length($SSHOME) == 0)
	{
		die "Environment variable SS_HOME must point to where SS.EXE is located.";
	}
	$REPOS = $ENV{'CVSROOT'} unless length($REPOS) > 0;

	$ENV{'SSDIR'} = $SSREPO;
	$SSCMD = "$SSHOME";
	if ($SSCMD !~ /^\".*/)
	{
		$SSCMD = "\"$SSCMD\"";
	}
	$SSCMD =~ s/\"(.*)\"/\"$1\\ss.exe\"/;

	my $banner = "Visual SourceSafe to cvs Migration Tool.\n" .
				"Based on a script by Brett Wooldridge (brettw\@riseup.com)\n" .
				"Updated for cvs by David Sykes (d.sykes\@pindar.com)\n" .
				"SourceSafe repository: $SSREPO\n" .
				"SourceSafe directory : $SSHOME\n" .
				"SourceSafe project	: $SSPROJ\n" .
				"Subversion repository: $REPOS\n\n";
	print "$banner";
	if ($DEBUG)
	{
		print STDERR "$banner";
	}
}


##############################################################
# Build project directory hierarchy
#
sub build_hierarchy
{
	if ($DEBUG)
	{
		print STDERR "\n#############################################################\n";
		print STDERR "#                  Subroutine: build_hierarchy              #\n";
		print STDERR "#############################################################\n";
	}

	my ( $cmd, $blank, $dir, @lines );

	$blank = "true";
	$dir = "";

	print "Building directory hierarchy...";

	$* = 1;
	$/ = ':';
	$cmd = $SSCMD . " Dir $SSPROJ -I- -R -F-";
	$_ = `$cmd`;

	if ($DEBUG)
	{
		print STDERR "Build Hierarchy: raw data";
		print STDERR "$_";
		print STDERR "#####################################################\n";
	}

	# what this next expression does is to merge wrapped lines like:
	#	$/DeviceAuthority/src/com/eclyptic/networkdevicedomain/deviceinterrogator/excep
	#	tion:
	# into:
	#	$/DeviceAuthority/src/com/eclyptic/networkdevicedomain/deviceinterrogator/exception:
	s/\n((\w*\-*\.*\w*\/*)+\:)/$1/g;
	
	if ($DEBUG)
	{
		print STDERR "Build Hierarchy: post process";
		print STDERR "$_";
	}

	$* = 0;
	$/ = "";
	@lines = split('\n');
	foreach $line (@lines)
	{
		if ($line =~ /(.*)\:/)
		{
			chop($line);
			push(@projects2, $line);
		}
	}

	@projects = sort(@projects2);	

	open(DIRS, "> directories.txt");
	foreach $line (@projects)
	{
			print STDERR "Project: $line\n";
		print DIRS "$line\n";
	}
	close(DIRS);
	
	my $count = @lines;
	print "\b\b\b:\tdone ($count dirs)\n";
	
	$PHASE = 1;
}


##############################################################
# Build a list of files from the list of directories
#
sub build_filelist
{
	if ($DEBUG)
	{
		print STDERR "\n#############################################################\n";
		print STDERR "#              Subroutine: build_filelist                   #\n";
		print STDERR "#############################################################\n";
	}

	my ( $proj, $cmd, $i, $j, $count );
	
	print "Building file list (  0%):		";

	$count = @projects;

	$i = 0;
	$j = 0.0;
	foreach $proj (@projects)
	{
		$* = 1;
		$/ = ':';

		$cmd = $SSCMD . " Dir -I- \"$proj\"";
		$_ = `$cmd`;

		# what this next expression does is to merge wrapped lines like:
		#	$/DeviceAuthority/src/com/eclyptic/networkdevicedomain/deviceinterrogator/excep
		#	tion:
		# into:
		#	$/DeviceAuthority/src/com/eclyptic/networkdevicedomain/deviceinterrogator/exception:
		s/\n((\w*\-*\.*\w*\/*)+\:)/$1/g;

		$* = 0;
		$/ = "";
		@lines = split('\n');
		foreach $line (@lines)
		{
			if ($line eq '' || length($line) == 0)
			{
			}
			elsif ($line !~ /(.*)\:/ && $line !~ /^\$.*/ &&
					$line !~ /^([0-9]+) item.*/ && $line !~ /^No items found.*/)
			{
				push(@filelist, "$proj/$line");
				printf("\b\b\b\b\b\b\b\b\b\b\b\b\b(%3d%%): %5d", (($j / $count) * 100), $i);
				if ($DEBUG)
				{
					print STDERR "$proj/$line\n";
				}
				$i++;
			}
		}
		$j++;
	}
	print "\b\b\b\b\b\b\b\b\b\b\b\b\b(100%):\tdone ($i files)\n";
}


##############################################################
# Build complete histories for all of the files in the project
#
sub build_histories
{
	if ($DEBUG)
	{
		print STDERR "\n#############################################################\n";
		print STDERR "#                  Subroutine: build_histories              #\n";
		print STDERR "#############################################################\n";
	}

	my ( $file, $pad, $padding, $oldname, $shortname, $diff );
	my ( $i, $count );
	
	print "Building file histories (  0%): ";

	$versioncount = 0;
	$count = @filelist;
	$i = 0.0;
	$diff = 0;
	$pad = "													 ";
	$oldName = "";
	$shortname = "";
	foreach $file (@filelist)
	{
		# display sugar
		($oldname = $file) =~ s/./\b/g;
		$shortname = substr($file, rindex($file,'/')+1);
		$diff = length($oldname) - length($shortname);
		$padding = ($diff > 0) ? substr($pad, 0, $diff) : "";
		print "$oldname";
		$tmpname = substr("$shortname$padding", 0, 45);
		printf("\b\b\b\b\b\b\b\b(%3d%%): %s", (($i / $count) * 100), $tmpname);
		$padding =~ s/./\b/g;
		print "$padding";
		$oldname = substr($shortname, 0 , 45);

		# real work
		$cmd = $SSCMD . " History -I- \"$file\"";
		$_ = `$cmd`;

		print STDERR "$cmd\n";
		print STDERR "$_\n";
		&proc_history($file, $_);

		$i++;
	}
	
	@sortedhist = sort(@histories);
	open(HIST, ">histories.txt");
	foreach $hist (@sortedhist)
	{
		print HIST "$hist\n";
	}
	close(HIST);

	$oldname =~ s/./\b/g;
	print "$oldname\b\b\b\b\b\b\b\b(100%):\tdone ($versioncount versions)" . substr($pad, 0, 20) . "\n"; 
}


##############################################################
# Restart from previously generated parsed project data
#
sub proc_history
{
	my $file = shift(@_);
	my $hist = shift(@_);

	$hist =~ s/Checked in\n/Checked in /g;

	use constant STATE_FILE	=> 0;
	use constant STATE_VERSION => 1;
	use constant STATE_USER	=> 2;
	use constant STATE_ACTION => 3;
	use constant STATE_COMMENT => 5;
	use constant STATE_FINAL => 6;
	
	my $state = STATE_VERSION;
	
	local $proj = $SSPROJ;
	$proj =~ s/(\$)/\\$1/g;
	$proj =~ s/(\/)/\\$1/g;

	my ( $version, $junk, $user, $date, $time, $month, $day, $year );
	my ( $hour, $minute, $path, $action );
	
	$comment = "";
	my @lines = split('\n', $hist);
	my $line_count = @lines;
	my $i = 0;
	foreach $line (@lines)
	{
		print STDERR "state is $state , line is '$line'\n";
		if ($state == STATE_VERSION && $line =~ /^\*+  Version ([0-9]+)/)
		{
			$versioncount++;
			$version = $1;
			$state = STATE_USER;
		}
		elsif ($state == STATE_USER && $line =~ /^User: /)
		{
			# At this point we have something along the lines of
			# User: Fred Blogs     Date: 20/06/05   Time: 13:22'

			($user , $dateinfo) = split("Date:",$line);
			($date , $time) = split("Time:",$dateinfo);
			$user =~ s/User: *//;
			$user =~ s/\s+$//sg;			# remove trailing space
			$date =~ s/^\s+//sg;			# remove leading space
			$date =~ s/\s+$//sg;			# remove trailing space
			$time =~ s/^\s+//sg;			# remove leading space
			$time =~ s/\s+$//sg;			# remove trailing space
			($day,$month,$year) = split('/', $date);
			($hour,$minute) = split(':', $time);
			$state = STATE_ACTION;
		}
		elsif ($state == STATE_ACTION)
		{
			if ($line =~ /^Checked in /)
			{
				if ($' =~ /^$proj/)
				{
					$path = $';
					$action = 'checkin';
					$state = STATE_COMMENT;
				}
				else
				{
					$proj = $';
					$action = 'checkin';
					$state = STATE_COMMENT;
				}
			}
			elsif ($line =~ /^Created/)
			{
				$action = 'created';
				$state = STATE_COMMENT;
			}
			elsif ($line =~ /^Labeled/)
			{
				#	Can we remove the dumdee label?
				if ( $labelname =~ /dumdee/ )
				{
					print STDERR "Label is dumdeed\n";
					$state = STATE_VERSION;
				}
				else
				{
					print STDERR "Label is not dumdeed\n";
					$action = 'Labeled';
					$comment = "Labeled $labelname";
					$state = STATE_FINAL;
				}
			}
			elsif ($line =~ /^Branched/)
			{
				#	Do nothing with this
				$state = STATE_VERSION;
			}
			elsif ($line =~ /^Rolled back/)
			{
				#	Do nothing with this
				$state = STATE_VERSION;
			}
			else
			{
				die "The action associated with ;$line' was not recognised. Stopped";
			}
#			elsif ($line =~ / added/)
#			{
#				$path = $`;
#				$action = 'added';
#				$state = STATE_COMMENT;
#			}
#			elsif ($line =~ / deleted/)
#			{
#				$path = $`;
#				$action = 'deleted';
#				$state = STATE_COMMENT;
#			}
#			elsif ($line =~ / deleted/)
#			{
#				$path = $`;
#				$action = 'deleted';
#				$state = STATE_COMMENT;
#			}
		}
		elsif ($state == STATE_COMMENT)
		{
			if ($line =~ /^Comment\:/)
			{
				$comment = $';
			}
			elsif (length($comment) > 0 && length($line) > 0)
			{
				$comment = $comment . ' ' . $line;
			}
			elsif (length($line) == 0)
			{
				$comment =~ s/^\s+(.*)/$1/g;
				$comment =~ s/\"/\\\"/g;
				# Commas are used as seperators for the history parameters, so don't allow them in comments
				$comment =~ s/,/;/g;
				$state = STATE_FINAL;
			}
		}

		$i++;

		if ($state == STATE_FINAL)
		{
			$year = ($year < 80) ? 2000+$year : 1900+$year;
			$hist = join(',', $file, sprintf("%04d", $version), "$year/" . sprintf("%02d/", $month) . sprintf("%02d ", $day) .
					sprintf("%02d:", $hour) . $minute, $user, $action,
					"\"$user: $year/" . printf("%02d", $month) . "/" . sprintf("%02d ", $day) . sprintf("%02d:", $hour) . $minute . " $comment\"");
			print STDERR "History info = '$hist'";
			$comment = "";
			if ($DEBUG)
			{
			 print STDERR "$hist\n";
			}
			push(@histories, $hist);
			$state = STATE_VERSION;
		}
		elsif ($i == $line_count)
		{
			#	Something spooky might be going on here, the original script used this as a STATE_FINAL which added
			#	non existant versions. If state is not STATE_VERSION an error might have occured
			if ($state ne STATE_VERSION)
			{
				die "Invalid state $state at end of histories. Stopped";
			}
		}
	}
}


##############################################################
# Dump the users from the repository into users.txt and exit
#
sub dump_users
{
	for $hist (@histories)
	{
		local ($file, $version, $datetime, $user, $action, $comment) = split(',', $hist);
		$USERHASH{$user} = 1;
	}

	open(USERS, "> users.txt");
	foreach $user (keys %USERHASH)
	{
		print USERS "$user\n";
	}
	close(USERS);
	
	print "\nUsers.txt file has been created.  Use the list of users in this\n";
	print "file to create matching user accounts in Subversion.  Ensure that these\n";
	print "accounts initially have NO AUTHENTICATION, otherwise the migration will\n";
	print "likely fail.  Alternatively, you can use the --force-user option to\n";
	print "create all files with the same username.  Either way, you can restart\n";
	print "this migration, picking up from this point, by using the --restart\n";
	print "option on the command line.\n\n";
	exit 0;
}


##############################################################
# Restart from previously generated parsed project data
#
sub restart
{
	local($i) = 0;

	if (-f "directories.txt")
	{
		print "Loading directories:		";
	
		open(DIRS, "< directories.txt");
		while (<DIRS>)
		{
			$line = $_;
			chop($line);
			push(@projects, $line);
			$i++;
			printf("\b\b\b\b\b%5d", $i);
		}
		close(DIRS);
		print "\b\b\b\b\b\t\tdone ($i dirs)\n";
		$PHASE = 1;
	}
	
	if (-f "histories.txt")
	{
		print "Loading file histories:		";
		$i = 0;
		open(HIST, "< histories.txt");
		while (<HIST>)
		{
			$line = $_;
			chop($line);
			push(@sortedhist, $line);
			$i++;
			printf("\b\b\b\b\b%5d", $i);
		}
		close(HIST);
		print "\b\b\b\b\b\tdone ($i versions)\n";
		$PHASE = 3;
	}
	
	if (-f "extract_progress.txt")
	{
		local ($file, $version);
		print "Calculating extract progress:";
		open(EXTRACT, "< extract_progress.txt");
		while (<EXTRACT>)
		{
			$RESTARTFILE = $_;
			chop($RESTARTFILE);
			($file, $version) = split(',', $RESTARTFILE);
			$created{$file} = 1;
		}
		close(EXTRACT);
		
		$RESTARTFILE =~ s/(\$)/\\$1/g;
		$RESTARTFILE =~ s/(\/)/\\$1/g;
		if ($DEBUG)
		{
			print STDERR "Restart from: $RESTARTFILE\n";
		}
		$file =~ s/^$proj(.*)/$1/g;
		$file = substr($file, rindex($file, '/')+1);
		print "\trestart from $file (v.$version)\n";
		$PHASE = 4;
	}
}


##############################################################
# Create the directory hierarchy in the local filesystem
#
sub create_directories
{
	if ($DEBUG)
	{
		print STDERR "\n#############################################################\n";
		print STDERR "#               Subroutine: create_directories              #\n";
		print STDERR "#############################################################\n";
	}
	
	my $proj = $SSPROJ;
	$proj =~ s/(\$)/\\$1/g;
	$proj =~ s/(\/)/\\$1/g;

	my ($basedir) = $SSPROJ;
	$basedir =~ s/^\$\///g;

	print "Creating local directories: ";
	&recursive_delete('./work');
	mkdir('./work');
	chdir('./work');

	my @dircomponents = split('/', $basedir . '/');
	my $buildupdir = '.';
	foreach $dir (@dircomponents)
	{
		$buildupdir = $buildupdir . '/' . $dir;
		mkdir($buildupdir);
		if ($DEBUG)
		{
			print STDERR "Creating base dir '$buildupdir'\n";
		}
		importmodule($buildupdir);
	}

	foreach $dir (@projects)
	{
		if ($dir =~ /^$proj\//)
		{
			my $rawdir = "$basedir/$'";
			mkdir($rawdir);
			if ($DEBUG)
			{
				print STDERR "Creating project dir '$rawdir'\n";
			}

			importmodule($rawdir);
		}
	}
	print "\tdone\n";
	chdir("..");
	&pcwd();
}


##############################################################
# Delete a directory tree and all of its files recursively
#
sub recursive_delete
{
	my ($parent) = @_;	
	my ( @dirs, $dir );

	opendir(DIR, $parent);
	@dirs = readdir(DIR);
	closedir(DIR);
	foreach $dir (@dirs)
	{
		if ($dir ne '.' && $dir ne '..')
		{
			recursive_delete("$parent/$dir");
		}
	}
	
	if (-d $parent)
	{
		rmdir($parent);
	}
	elsif (-f $parent)
	{
		unlink($parent);
	}
}


##############################################################
# Import a directory hierarchy into Subversion
#
sub import_directories
{
	return;

	if ($DEBUG)
	{
		print STDERR "\n#############################################################\n";
		print STDERR "#                     Subroutine: import_directories        #\n";
		print STDERR "#############################################################\n";
	}

	print "Importing directories: ";
	
	my ($basedir) = $SSPROJ;
	$basedir =~ s/^\$\///g;

#	my $cmd = "svn --message \"initial import\" import . \"$REPOS\"";
	my $cmd = "cvs import -C -d -m \"Initial Import 1\" \"$basedir\" Pindar";
	if ($DEBUG)
	{
		print STDERR "$cmd\n";
	}

	chdir('./work');
	`$cmd`;
	chdir('..');

	print "\t\tdone\n";
}


##############################################################
# Checkout a copy of the directory hierarchy so that we have
# a Subversion local working copy
#
sub checkout_directories
{
	if ($DEBUG)
	{
		print STDERR "\n#############################################################\n";
		print STDERR "#           Subroutine: checkout_directories                #\n";
		print STDERR "#############################################################\n";
	}

	print "Checking out directories: ";
	
	my ($basedir) = $SSPROJ;
	$basedir =~ s/^\$\///g;

#	my $cmd = "svn --non-interactive checkout \"$REPOS/$basedir\" \"./work/$basedir\"";
	my $cmd = "cvs checkout -R $basedir";
	if ($DEBUG)
	{
		print STDERR "$cmd\n";
	}

	&recursive_delete('./work');
	mkdir('./work');
	chdir('./work');
	`$cmd`;
	chdir('..');
	print "\tdone\n";
}


##############################################################
# This is the meat.  Extract each version of each file in the
# project from VSS and check it into Subversion
#
sub extract_and_import
{
	if ($DEBUG)
	{
		print STDERR "\n#############################################################\n";
		print STDERR "#                Subroutine: extract_and_import             #\n";
		print STDERR "#############################################################\n";
	}

	my ( $file, $padding );

	print "Extracting and creating (  0%%): ";

	open(EXTRACT, "> extract_progress.txt");

	if (defined($RESTARTFILE))
	{
		while ($#sortedhist > 0)
		{
		 $hist = shift(@sortedhist);
		 last if ($hist =~ /^$RESTARTFILE(.*)/);
		 if ($DEBUG)
		 {
			print STDERR "$hist\n";
		 }
		}
	}

	my $proj = $SSPROJ;
	$proj =~ s/(\$)/\\$1/g;
	$proj =~ s/(\/)/\\$1/g;

	my ($basedir) = $SSPROJ;
	$basedir =~ s/^\$\///g;

	my $count = @sortedhist;
	my $i = 0.0;
	my $diff = 0;
   my $pad = "                                                     ";
	my $oldName = "";
	my $shortname = "";
	my $oldname = "";
	
	chdir('./work');
	foreach $hist (@sortedhist)
	{
		my ($file, $version, $datetime, $user, $action, $comment) = split(',', $hist);

		print STDERR "-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n";
		print STDERR "File = $file, version $version, action $action\n";

		# display sugar
		$oldname =~ s/./\b/g;
		$shortname = substr($file, &min(rindex($file,'/')+1, 40)) . ' (v.' . int($version) . ')';
		$diff = length($oldname) - length($shortname);
		$padding = ($diff > 0) ? substr($pad, 0, $diff) : "";
		print "$oldname";
		$tmpname = substr("$shortname$padding", 0, 46);
		printf("\b\b\b\b\b\b\b\b(%3d%%): %s", (($i / $count) * 100), $tmpname);
		$padding =~ s/./\b/g;
		print "$padding";
		$oldname = substr($shortname, 0 , 46);

		# chdir to the proper directory		
		print STDERR "---Path begins as $path\n";
		$path = substr($file, 0, rindex($file, '/'));
		print STDERR "---Path becomes $path\n";
		$path =~ s/^$proj(.*)/$1/g;
		print STDERR "---Path becomes $path\n";
		$path = "$basedir$path";
		print STDERR "---Path becomes $path\n";

		# extract the file from VSS
		$ver = int($version);

		$cmd = $SSCMD . " get -GTM -W -I- -GL\"$path\" -V" . int($ver) . " \"$file\"";
		if ($DEBUG)
		{
			print STDERR "$cmd\n";
		}
		$out = `$cmd`;
		if ($DEBUG)
		{
			print STDERR "out='$out'";
		}
		
		if (defined($FORCEUSER))
		{
			$user = $FORCEUSER;
		}

		my $tmpdir = $basedir;
		print STDERR "Change to directory $tmpdir\n";
		chdir($tmpdir);
		if ( $created{$file} > 0 )
		{
			if ($file =~ /^$proj\//)
			{
#				$cmd2 = "svn commit --non-interactive --non-recursive --username $user --message $comment \"$'\"";
				$cmd2 = "cvs commit -l -m $comment \"$'\"";
				$out = `$cmd2`;
				if ($DEBUG)
				{
				 print STDERR "$cmd2\n";
				 print STDERR "$out";
				}
				print EXTRACT "$file,$version\n";
			}
		}
		else # ($action eq 'created' || $action eq 'added')
		{
			if ($file =~ /^$proj\//)
			{
				$cmd3 = "cvs add \"$'\"";
				if ($DEBUG)
				{
					print STDERR "$cmd3\n";
				}
				$out = `$cmd3`;
				if ($DEBUG)
				{
					print STDERR "$out";
				}
				$cmd3 = "cvs commit -l -m $comment \"$'\"";
				if ($DEBUG)
				{
					print STDERR "$cmd3\n";
				}
				$out = `$cmd3`;
				if ($DEBUG)
				{
					print STDERR "$out";
				}
				$created{$file} = 1;
				print EXTRACT "$file,$version\n";
			}
		}

		@dirstomove = split( "/" , $tmpdir );
		foreach ( @dirstomove )
		{
			chdir("..");
		}

		$i++;
	}
	close(EXTRACT);
	$oldname =~ s/./\b/g;
	print "$oldname\b\b\b\b\b\b\b\b(100%):\t" . substr("done$pad", 46) . "\n";
}


##############################################################
# Find the minimum value between two integers
#
sub min
{
	local $one = shift(@_);
	local $two = shift(@_);
	
	return ($one < $two ? $one : $two);
}


##############################################################
# Print the current working directory
#
sub pcwd
{
	$cmd = "dir";
	$out = `$cmd`;
	@dirlines = split ( "\n" , $out );
	print STDERR "$dirlines[3]\n";
}

##############################################################
# Import a module into cvs
#
sub importmodule()
{
	print STDERR "---------------------------\n";
	print STDERR "- importmodule $_[0]\n";
	chdir($_[0]);
	pcwd();

	my $cmd = "cvs import -C -d -m \"Initial Import2\" \"$_[0]\" Pindar";
	if ($DEBUG)
	{
		print STDERR "$cmd\n";
	}
	`$cmd`;

	@dirstomove = split( "/" , $_[0] );
	foreach $dirparam ( @dirstomove )
	{
		if ( $dirparam ne '.')
		{
			chdir("..");
		}
	}
	pcwd();
	print STDERR "+++++++++++++++++++++++++++\n";
}
